{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# [模型训练、评估与推理](https://www.paddlepaddle.org.cn/documentation/docs/zh/guides/beginner/train_eval_predict_cn.html)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/usr/lib/python3/dist-packages/urllib3/util/selectors.py:14: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated since Python 3.3, and in 3.10 it will stop working\n",
      "  from collections import namedtuple, Mapping\n",
      "/usr/lib/python3/dist-packages/urllib3/_collections.py:2: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated since Python 3.3, and in 3.10 it will stop working\n",
      "  from collections import Mapping, MutableMapping\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "CUDAPlace(0)"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import paddle\n",
    "\n",
    "# 指定在 CPU 上训练\n",
    "# paddle.device.set_device(\"cpu\")\n",
    "\n",
    "# 指定在 GPU 第 0 号卡上训练\n",
    "paddle.device.set_device('gpu:0')\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/usr/local/lib/python3.8/dist-packages/ipykernel/ipkernel.py:283: DeprecationWarning: `should_run_async` will not call `transform_cell` automatically in the future. Please pass the result to `transformed_cell` argument and any exception that happen during thetransform in `preprocessing_exc_tuple` in IPython 7.17 and above.\n",
      "  and should_run_async(code)\n"
     ]
    }
   ],
   "source": [
    "from paddle.vision.transforms import Normalize\n",
    "\n",
    "transform = Normalize(mean=[127.5], std=[127.5], data_format=\"CHW\")\n",
    "# 加载 MNIST 训练集和测试集\n",
    "train_dataset = paddle.vision.datasets.MNIST(mode=\"train\", transform=transform)\n",
    "test_dataset = paddle.vision.datasets.MNIST(mode=\"test\", transform=transform)\n",
    "\n",
    "# 模型组网，构建并初始化一个模型 mnist\n",
    "mnist = paddle.nn.Sequential(\n",
    "    paddle.nn.Flatten(1, -1),\n",
    "    paddle.nn.Linear(784, 512),\n",
    "    paddle.nn.ReLU(),\n",
    "    paddle.nn.Dropout(0.2),\n",
    "    paddle.nn.Linear(512, 10),\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 封装模型为一个 model 实例，便于进行后续的训练、评估和推理\n",
    "model = paddle.Model(mnist)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 为模型训练做准备，设置优化器及其学习率，并将网络的参数传入优化器，设置损失函数和精度计算方式\n",
    "model.prepare(\n",
    "    optimizer=paddle.optimizer.Adam(\n",
    "        learning_rate=0.001, parameters=model.parameters()\n",
    "    ),\n",
    "    loss=paddle.nn.CrossEntropyLoss(),\n",
    "    metrics=paddle.metric.Accuracy(),\n",
    ")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The loss value printed in the log is the current step, and the metric is the average value of previous steps.\n",
      "Epoch 1/5\n",
      "step  10/938 [..............................] - loss: 1.1959 - acc: 0.3828 - ETA: 26s - 29ms/step"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/usr/local/lib/python3.8/dist-packages/paddle/fluid/layers/utils.py:77: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated since Python 3.3, and in 3.10 it will stop working\n",
      "  return (isinstance(seq, collections.Sequence) and\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "step 938/938 [==============================] - loss: 0.2987 - acc: 0.9032 - 11ms/step          \n",
      "Epoch 2/5\n",
      "step 938/938 [==============================] - loss: 0.0497 - acc: 0.9491 - 12ms/step          \n",
      "Epoch 3/5\n",
      "step 938/938 [==============================] - loss: 0.0129 - acc: 0.9600 - 11ms/step          \n",
      "Epoch 4/5\n",
      "step 938/938 [==============================] - loss: 0.0245 - acc: 0.9630 - 11ms/step          \n",
      "Epoch 5/5\n",
      "step 938/938 [==============================] - loss: 0.3321 - acc: 0.9678 - 12ms/step          \n"
     ]
    }
   ],
   "source": [
    "# 启动模型训练，指定训练数据集，设置训练轮次，设置每次数据集计算的批次大小，设置日志格式\n",
    "model.fit(train_dataset, epochs=5, batch_size=64, verbose=1)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Eval begin...\n",
      "step 10000/10000 [==============================] - loss: 5.9605e-07 - acc: 0.9713 - 3ms/step          \n",
      "Eval samples: 10000\n",
      "{'loss': [5.960463e-07], 'acc': 0.9713}\n"
     ]
    }
   ],
   "source": [
    "# 用 evaluate 在测试集上对模型进行验证\n",
    "eval_result = model.evaluate(test_dataset, verbose=1)\n",
    "print(eval_result)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch: 0, batch_id: 900, loss is: [0.04298671], acc is: [0.984375]\n",
      "epoch: 1, batch_id: 900, loss is: [0.10581946], acc is: [0.984375]\n",
      "epoch: 2, batch_id: 900, loss is: [0.08009005], acc is: [0.96875]\n",
      "epoch: 3, batch_id: 900, loss is: [0.05954459], acc is: [0.96875]\n",
      "epoch: 4, batch_id: 900, loss is: [0.04359554], acc is: [0.96875]\n"
     ]
    }
   ],
   "source": [
    "# dataset与mnist的定义与使用高层API的内容一致\n",
    "# 用 DataLoader 实现数据加载\n",
    "train_loader = paddle.io.DataLoader(train_dataset, batch_size=64, shuffle=True)\n",
    "\n",
    "# 将mnist模型及其所有子层设置为训练模式。这只会影响某些模块，如Dropout和BatchNorm。\n",
    "mnist.train()\n",
    "\n",
    "# 设置迭代次数\n",
    "epochs = 5\n",
    "\n",
    "# 设置优化器\n",
    "optim = paddle.optimizer.Adam(parameters=mnist.parameters())\n",
    "# 设置损失函数\n",
    "loss_fn = paddle.nn.CrossEntropyLoss()\n",
    "for epoch in range(epochs):\n",
    "    for batch_id, data in enumerate(train_loader()):\n",
    "        x_data = data[0]  # 训练数据\n",
    "        y_data = data[1]  # 训练数据标签\n",
    "        predicts = mnist(x_data)  # 预测结果\n",
    "\n",
    "        # 计算损失 等价于 prepare 中loss的设置\n",
    "        loss = loss_fn(predicts, y_data)\n",
    "\n",
    "        # 计算准确率 等价于 prepare 中metrics的设置\n",
    "        acc = paddle.metric.accuracy(predicts, y_data)\n",
    "\n",
    "        # 下面的反向传播、打印训练信息、更新参数、梯度清零都被封装到 Model.fit() 中\n",
    "        # 反向传播\n",
    "        loss.backward()\n",
    "\n",
    "        if (batch_id + 1) % 900 == 0:\n",
    "            print(\n",
    "                \"epoch: {}, batch_id: {}, loss is: {}, acc is: {}\".format(\n",
    "                    epoch, batch_id + 1, loss.numpy(), acc.numpy()\n",
    "                )\n",
    "            )\n",
    "        # 更新参数\n",
    "        optim.step()\n",
    "        # 梯度清零\n",
    "        optim.clear_grad()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "batch_id: 30, loss is: [0.1361749], acc is: [0.953125]\n",
      "batch_id: 60, loss is: [0.30759424], acc is: [0.90625]\n",
      "batch_id: 90, loss is: [0.12815635], acc is: [0.96875]\n",
      "batch_id: 120, loss is: [0.00055354], acc is: [1.]\n",
      "batch_id: 150, loss is: [0.01452945], acc is: [0.984375]\n"
     ]
    }
   ],
   "source": [
    "# 加载测试数据集\n",
    "test_loader = paddle.io.DataLoader(test_dataset, batch_size=64, drop_last=True)\n",
    "# 设置损失函数\n",
    "loss_fn = paddle.nn.CrossEntropyLoss()\n",
    "# 将该模型及其所有子层设置为预测模式。这只会影响某些模块，如Dropout和BatchNorm\n",
    "mnist.eval()\n",
    "# 禁用动态图梯度计算\n",
    "for batch_id, data in enumerate(test_loader()):\n",
    "    x_data = data[0]  # 测试数据\n",
    "    y_data = data[1]  # 测试数据标签\n",
    "    predicts = mnist(x_data)  # 预测结果\n",
    "\n",
    "    # 计算损失与精度\n",
    "    loss = loss_fn(predicts, y_data)\n",
    "    acc = paddle.metric.accuracy(predicts, y_data)\n",
    "\n",
    "    # 打印信息\n",
    "    if (batch_id + 1) % 30 == 0:\n",
    "        print(\n",
    "            \"batch_id: {}, loss is: {}, acc is: {}\".format(\n",
    "                batch_id + 1, loss.numpy(), acc.numpy()\n",
    "            )\n",
    "        )\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "predict finished\n",
      "true label: 7, pred label: 7\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<matplotlib.image.AxesImage at 0x7ff7545ed6d0>"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 加载测试数据集\n",
    "test_loader = paddle.io.DataLoader(test_dataset, batch_size=64, drop_last=True)\n",
    "# 将该模型及其所有子层设置为预测模式\n",
    "mnist.eval()\n",
    "for batch_id, data in enumerate(test_loader()):\n",
    "    # 取出测试数据\n",
    "    x_data = data[0]\n",
    "    # 获取预测结果\n",
    "    predicts = mnist(x_data)\n",
    "print(\"predict finished\")\n",
    "\n",
    "# 从测试集中取出一组数据\n",
    "img, label = test_loader().next()\n",
    "\n",
    "# 执行推理并打印结果\n",
    "pred_label = mnist(img)[0].argmax()\n",
    "print(\n",
    "    \"true label: {}, pred label: {}\".format(\n",
    "        label[0].item(), pred_label[0].item()\n",
    "    )\n",
    ")\n",
    "# 可视化图片\n",
    "from matplotlib import pyplot as plt\n",
    "\n",
    "plt.imshow(img[0][0])\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "本节中介绍了在飞桨框架中使用高层 API 进行模型训练、评估和推理的方法，并拆解出对应的基础 API 实现方法。需要注意的是，这里的推理仅用于模型效果验证，实际生产应用中，则可使用飞桨提供的一系列推理部署工具，满足服务器端、移动端、网页/小程序等多种环境的模型部署上线需求，具体可参见 推理部署 章节。\n",
    "\n",
    "同时，飞桨的高层 API 和基础 API 可以组合使用，并不是完全割裂开的，这样有助于开发者更便捷地完成算法迭代。示例代码如下：\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/usr/local/lib/python3.8/dist-packages/ipykernel/ipkernel.py:283: DeprecationWarning: `should_run_async` will not call `transform_cell` automatically in the future. Please pass the result to `transformed_cell` argument and any exception that happen during thetransform in `preprocessing_exc_tuple` in IPython 7.17 and above.\n",
      "  and should_run_async(code)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The loss value printed in the log is the current step, and the metric is the average value of previous steps.\n",
      "Epoch 1/5\n",
      "step 938/938 [==============================] - loss: 0.0526 - acc: 0.9290 - 13ms/step          \n",
      "Eval begin...\n",
      "step 157/157 [==============================] - loss: 0.0041 - acc: 0.9709 - 10ms/step          \n",
      "Eval samples: 10000\n",
      "Epoch 2/5\n",
      "step 938/938 [==============================] - loss: 0.0379 - acc: 0.9742 - 15ms/step          \n",
      "Eval begin...\n",
      "step 157/157 [==============================] - loss: 3.2117e-04 - acc: 0.9803 - 13ms/step        \n",
      "Eval samples: 10000\n",
      "Epoch 3/5\n",
      "step 938/938 [==============================] - loss: 0.0566 - acc: 0.9799 - 16ms/step          \n",
      "Eval begin...\n",
      "step 157/157 [==============================] - loss: 0.0274 - acc: 0.9804 - 12ms/step            \n",
      "Eval samples: 10000\n",
      "Epoch 4/5\n",
      "step 938/938 [==============================] - loss: 0.1188 - acc: 0.9827 - 17ms/step          \n",
      "Eval begin...\n",
      "step 157/157 [==============================] - loss: 0.0032 - acc: 0.9815 - 14ms/step            \n",
      "Eval samples: 10000\n",
      "Epoch 5/5\n",
      "step 938/938 [==============================] - loss: 0.0089 - acc: 0.9841 - 15ms/step          \n",
      "Eval begin...\n",
      "step 157/157 [==============================] - loss: 7.5250e-05 - acc: 0.9818 - 15ms/step        \n",
      "Eval samples: 10000\n"
     ]
    },
    {
     "ename": "",
     "evalue": "",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m在当前单元格或上一个单元格中执行代码时 Kernel 崩溃。\n",
      "\u001b[1;31m请查看单元格中的代码，以确定故障的可能原因。\n",
      "\u001b[1;31m单击<a href='https://aka.ms/vscodeJupyterKernelCrash'>此处</a>了解详细信息。\n",
      "\u001b[1;31m有关更多详细信息，请查看 Jupyter <a href='command:jupyter.viewOutput'>log</a>。"
     ]
    }
   ],
   "source": [
    "from paddle.vision.models import LeNet\n",
    "\n",
    "\n",
    "class FaceNet(paddle.nn.Layer):\n",
    "    def __init__(self):\n",
    "        super().__init__()\n",
    "        # 使用高层API组网\n",
    "        self.backbone = LeNet()\n",
    "        # 使用基础API组网\n",
    "        self.outLayer1 = paddle.nn.Sequential(\n",
    "            paddle.nn.Linear(10, 512), paddle.nn.ReLU(), paddle.nn.Dropout(0.2)\n",
    "        )\n",
    "        self.outLayer2 = paddle.nn.Linear(512, 10)\n",
    "\n",
    "    def forward(self, inputs):\n",
    "        out = self.backbone(inputs)\n",
    "        out = self.outLayer1(out)\n",
    "        out = self.outLayer2(out)\n",
    "        return out\n",
    "\n",
    "\n",
    "# 使用高层API封装网络\n",
    "model = paddle.Model(FaceNet())\n",
    "# 使用基础API定义优化器\n",
    "optim = paddle.optimizer.Adam(learning_rate=1e-3, parameters=model.parameters())\n",
    "# 使用高层API封装优化器和损失函数\n",
    "model.prepare(\n",
    "    optim, paddle.nn.CrossEntropyLoss(), metrics=paddle.metric.Accuracy()\n",
    ")\n",
    "# 使用高层API训练网络\n",
    "model.fit(train_dataset, test_dataset, epochs=5, batch_size=64, verbose=1)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
